home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / src / xad_MSA.lha / MSA.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-20  |  4.9 KB  |  149 lines

  1. /* Magic Shadow Archiver (MSA) disk archiver client for XAD.
  2.  * Copyright (C) 2000 Stuart Caie <kyzer@4u.net>
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  * 
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  * 
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */
  18.  
  19. /* This XAD client reads 'Magic Shadow Archiver' disk images and writes
  20.  * them out as '.ST' (raw Atari ST disk) files, or allows them to be
  21.  * written to MSDOS/GEM-formatted disks.
  22.  *
  23.  * $VER: MSA.c 1.1 (06.08.2000)
  24.  *
  25.  * File format info from Damien Burke,
  26.  * see http://www.jetman.dircon.co.uk/st/
  27.  */
  28.  
  29. #include <libraries/xadmaster.h>
  30. #include <proto/xadmaster.h>
  31.  
  32. #include "SDI_compiler.h"
  33. #include "ConvertE.c"
  34.  
  35. #ifndef XADMASTERFILE
  36. #define MSA_Client      FirstClient
  37. #define NEXTCLIENT      NULL
  38. const UBYTE version[] = "$VER: MSA 1.1 (06.08.2000)";
  39. #endif
  40. #define MSA_VERSION     1
  41. #define MSA_REVISION    1
  42.  
  43. #define XADBASE REG(a6, struct xadMasterBase *xadMasterBase)
  44.  
  45. /* work-doing macros */
  46. #define SKIP(offset) if ((err = xadHookAccess(XADAC_INPUTSEEK, \
  47.   (ULONG)(offset), NULL, ai))) goto exit_handler
  48. #define READ(buffer,length) if ((err = xadHookAccess(XADAC_READ, \
  49.   (ULONG)(length), (APTR)(buffer), ai))) goto exit_handler
  50. #define WRITE(buffer,length) if ((err = xadHookAccess(XADAC_WRITE, \
  51.   (ULONG)(length), (APTR)(buffer), ai))) goto exit_handler
  52. #define COPY(length) if ((err = xadHookAccess(XADAC_COPY, \
  53.   (ULONG)(length), NULL, ai))) goto exit_handler
  54. #define ALLOC(t,v,l) if (!((v) = (t) xadAllocVec((l),0))) ERROR(NOMEMORY)
  55. #define FREE(obj) xadFreeObjectA((APTR)(obj),NULL)
  56. #define ERROR(error) do { err = XADERR_##error; goto exit_handler; } while(0)
  57.  
  58.  
  59.  
  60. ASM(BOOL) MSA_RecogData(REG(d0, ULONG size), REG(a0, UBYTE *d), XADBASE) {
  61.   return (BOOL) (d[0]==0x0E &&d[1]==0x0F && d[4]==0 && d[5]<2);
  62. }
  63.  
  64. ASM(LONG) MSA_GetInfo(REG(a0, struct xadArchiveInfo *ai), XADBASE) {
  65.   struct xadDiskInfo *xdi;
  66.   UBYTE buffer[10];
  67.   LONG err;
  68.  
  69.   /* it's so simple here, I won't use the normal ALLOCOBJ/READ macros */
  70.   xdi = (struct xadDiskInfo *) xadAllocObjectA(XADOBJ_DISKINFO, NULL);
  71.   if (!(ai->xai_DiskInfo = xdi)) return XADERR_NOMEMORY;
  72.   if ((err = xadHookAccess(XADAC_READ, 10, (APTR)&buffer, ai))) return err;
  73.  
  74.   xdi->xdi_EntryNumber  = 1;
  75.   xdi->xdi_TrackSectors = EndGetM16(&buffer[2]);
  76.   xdi->xdi_Heads        = EndGetM16(&buffer[4]) + 1;
  77.   xdi->xdi_LowCyl       = EndGetM16(&buffer[6]);
  78.   xdi->xdi_HighCyl      = EndGetM16(&buffer[8]);
  79.   xdi->xdi_SectorSize   = 512;
  80.   xdi->xdi_Cylinders    = xdi->xdi_HighCyl + 1;
  81.   xdi->xdi_CylSectors   = xdi->xdi_TrackSectors * xdi->xdi_Heads;
  82.   xdi->xdi_TotalSectors = xdi->xdi_Cylinders * xdi->xdi_CylSectors;
  83.   xdi->xdi_Flags        = XADDIF_SEEKDATAPOS | XADDIF_GUESSCYLINDERS;
  84.   xdi->xdi_DataPos      = 10;
  85.   return XADERR_OK;
  86. }
  87.  
  88. ASM(LONG) MSA_UnArchive(REG(a0, struct xadArchiveInfo *ai), XADBASE) {
  89.   UBYTE buffer[2], *in = NULL, *out, *i, *o, *end, code;
  90.   struct xadDiskInfo *di = ai->xai_CurDisk;
  91.   UWORD inlen = 0, outlen = di->xdi_TrackSectors << 9;
  92.   UWORD trklen, run, cyl, head;
  93.   LONG err = XADERR_OK;
  94.  
  95.   /* allocate output buffer */
  96.   ALLOC(UBYTE *, out, outlen);
  97.  
  98.   for (cyl = di->xdi_LowCyl; cyl <= ai->xai_HighCyl; cyl++) {
  99.     for (head = 0; head < di->xdi_Heads; head++) {
  100.       READ(&buffer, 2);
  101.       trklen = EndGetM16(buffer);
  102.       if (cyl >= ai->xai_LowCyl) {
  103.         if (trklen >  outlen) { ERROR(OUTPUT); }
  104.         if (trklen == outlen) { COPY(trklen);  }
  105.         else {
  106.           /* (re)allocate input buffer if necessary */
  107.           if (trklen > inlen) {
  108.             if (in) FREE(in);
  109.             ALLOC(UBYTE *, in, (inlen = trklen));
  110.           }
  111.  
  112.           /* read and un-RLE this track's data */
  113.           READ(in, trklen);
  114.           i   = in;
  115.           o   = out;
  116.           end = out + outlen;
  117.           while (o < end) {
  118.             if ((code = *i++) != 0xE5) *o++ = code;
  119.             else {
  120.               code = *i; run = EndGetM16(i+1); i += 3;
  121.               if (o+run > end) ERROR(OUTPUT);
  122.               while (run--) *o++ = code;
  123.             }
  124.           }
  125.           WRITE(out, outlen);
  126.         }
  127.       }
  128.       else {
  129.         SKIP(trklen);
  130.       }
  131.     }
  132.   }
  133.  
  134. exit_handler:
  135.   if (in)  FREE(in);
  136.   if (out) FREE(out);
  137.   return err;
  138. }
  139.  
  140. const struct xadClient MSA_Client = {
  141.   NEXTCLIENT, XADCLIENT_VERSION, 4, MSA_VERSION, MSA_REVISION,
  142.   10, XADCF_DISKARCHIVER|XADCF_FREEDISKINFO,
  143.   0, "MSA",
  144.   (BOOL (*)()) MSA_RecogData,
  145.   (LONG (*)()) MSA_GetInfo,
  146.   (LONG (*)()) MSA_UnArchive,
  147.   NULL
  148. };
  149.